package com.hctforgreen.greenservice.utils;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.URL;

import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.util.LruCache;

import com.mato.sdk.proxy.Proxy;

/**
 * 异步加载缓存图片，增加从软引用中读取图片url的md5�?
 * 
 * @author Tallen Zhai
 * 
 */
public class AsyncImageLoader {
	// private Map<String, SoftReference<Drawable>> imageCache = new
	// HashMap<String, SoftReference<Drawable>>();

	private LruCache<String, Drawable> imageCache;

	public AsyncImageLoader() {
		// 获取最大的可用空间，若是须要的空间超出这个大小，则会抛出OutOfMemory异常

		// LrcCache机关函数中的参数是以千字节为单位的
		int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
		// 此处缓存大小取可用内存的1/8
		int cacheSize = maxMemory / 8;
		imageCache = new LruCache<String, Drawable>(cacheSize) {
			@Override
			protected int sizeOf(String key, Drawable drawable) {
				BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
				Bitmap bitMap = bitmapDrawable.getBitmap();

				// The cache size will be measured in kilobytes rather than

				// number of items.

				// 缓存的大小会应用千字节来衡量
				if (bitMap != null && !bitMap.isRecycled()) {
					return bitMap.getRowBytes() * bitMap.getHeight();
				} else {
					return 0;
				}

			}

		};
	}

	/**
	 * 加载图片
	 * 
	 * @param imageUrl
	 *            图片网络地址
	 * @param context
	 *            上下�?
	 * @param isSaveIcon
	 *            是否缓存图片（默认缓存图片名称为imageUrl的Md5�?
	 * @param callback
	 *            回调接口
	 * @return Drawable 加载的图�?
	 */
	public Drawable loadDrawable(final String imageUrl, final Context context,
			final boolean isSaveIcon, final ImageCallback callback) {
		final String md5Url = Md5Util.md5(imageUrl);
		if (imageCache.get(md5Url) != null) {

			return imageCache.get(md5Url);

		}
		if (FolderOper.isExistSdcard(context)) {
			File file = new File(HctConstants.DEFAULT_ROOT_PATH
					+ HctConstants.DEFAULT_CACHE_STORE_PATH + md5Url);

			
			if (file.exists()) {
				DecodeBitmapUtil bitmapUtil = new DecodeBitmapUtil();

				// Bitmap bitmap =
				// BitmapFactory.decodeFile(file.getAbsolutePath());
				/**
				 * 等比缩放一下
				 */
				Bitmap bitmap = bitmapUtil.decodeBitmap(file.getAbsolutePath());
				BitmapDrawable bd = new BitmapDrawable(bitmap);
				return bd;
			}
		}
		final Handler handler = new Handler() {
			@Override
			public void handleMessage(Message msg) {
				callback.imageLoaded((Drawable) msg.obj, md5Url);
			}
		};

		if (imageCache.get(md5Url) == null) {
			new Thread() {
				public void run() {
					Drawable drawable = loadImageFromUrl(imageUrl, md5Url,
							context, isSaveIcon);

					if (md5Url != null && drawable != null) {
						imageCache.put(md5Url, drawable);
					}
					handler.sendMessage(handler.obtainMessage(0, drawable));
				};
			}.start();
		}
		return null;
	}

	protected Drawable loadImageFromUrl(String imageUrl, Context context,
			boolean isSaveIcon) {
		return loadImageFromUrl(imageUrl, Md5Util.md5(imageUrl), context,
				isSaveIcon);
	}

	protected Drawable loadImageFromUrl(String imageUrl, String savePhotoName,
			Context context, boolean isSaveIcon) {
		try {
			if (imageUrl.equals("null") || imageUrl.equals("")) {
				return null;
			}
			HttpURLConnection httpcon = null;
			if (Proxy.getAddress() != null) {
				final URL url = new URL(imageUrl);
				String host = Proxy.getAddress().getHost();
				int port = Proxy.getAddress().getPort();
				final java.net.Proxy proxy = new java.net.Proxy(
						java.net.Proxy.Type.HTTP, new InetSocketAddress(host,
								port));
				httpcon = (HttpURLConnection) url.openConnection(proxy);
			} else {
				httpcon = (HttpURLConnection) new URL(imageUrl)
						.openConnection();
			}
			httpcon.setRequestMethod("GET");
			httpcon.setRequestProperty("User-Agent", "NetFox");
			httpcon.setRequestProperty("Accept-Encoding", "identity");
			httpcon.setConnectTimeout(30000);
			httpcon.connect();
			Drawable drawable = saveGifBitmap(savePhotoName, context,
					isSaveIcon, httpcon);
			return drawable;
		} catch (Exception e) {
			// 下载失败处理
			File iconFile = new File(HctConstants.DEFAULT_ROOT_PATH
					+ HctConstants.DEFAULT_CACHE_STORE_PATH + savePhotoName);
			if (iconFile.exists()) {
				iconFile.delete();
			}
			e.printStackTrace();
			return null;
		} finally {

		}
	}

	public static boolean copyStream(int httpContentLength, InputStream in,
			OutputStream out) {
		boolean bComplete = false;
		
		try {
			BufferedInputStream bin = new BufferedInputStream(in);
			BufferedOutputStream bout = new BufferedOutputStream(out);
			byte[] buf = new byte[1024];
			int len;
			int tmp = 0;
			while ((len = bin.read(buf)) > 0) {
				tmp += len;
				//Log.v("DATA", "BUFFER READ:" + new String(buf));
				bout.write(buf, 0, len);
			}
			
			if (tmp == httpContentLength) {
				bComplete = true;
			} else {
				bComplete = false;
			}
			bout.flush();
			out.flush();
			bin.close();
			in.close();
			bout.close();
			out.close();
		} catch (IOException e) {
			// TODO: handle exception
			e.printStackTrace();
		}
		
		return bComplete;
	}

	private Drawable saveGifBitmap(String savePhotoName, Context context,
			boolean isSaveIcon, HttpURLConnection httpcon) {

		try {
			InputStream is = httpcon.getInputStream();
			
			
			// 是否保存图标
			/**
			 * 2016-10-4
			 * 390694 修改
			 * 将通过available()方法获取的文件大小替换成通过getContentLength（）方法获取
			 * 因为available()方法在5.0以上的系统拿到的文件大小总是为0
			 */
			if (/*is.available() > 0*/ httpcon.getContentLength() > 0 && isSaveIcon) {
				if (FolderOper.isExistSdcard(context)) {
					// 创建文件�?
					try {
						FolderOper
								.createSDCardDir(HctConstants.DEFAULT_CACHE_STORE_PATH);
					} catch (Exception e) {
						e.printStackTrace();
					}

					File file = new File(HctConstants.DEFAULT_ROOT_PATH
							+ HctConstants.DEFAULT_CACHE_STORE_PATH
							+ savePhotoName);

					
					boolean bComplete = copyStream(httpcon.getContentLength(),
							is, new FileOutputStream(file));
					if (bComplete) {
						DecodeBitmapUtil bitmapUtil = new DecodeBitmapUtil();

						/**
						 * 等比缩放一下
						 */
						Bitmap bitmap = bitmapUtil.decodeBitmap(file
								.getAbsolutePath());
						BitmapDrawable bd = new BitmapDrawable(bitmap);
						return bd;
					} else if (!bComplete && file.exists()) {
						file.delete();
					}

				}
			}

		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
		return null;

	}

	private Drawable savePngBitmap(String savePhotoName, Context context,
			boolean isSaveIcon, HttpURLConnection httpcon) throws IOException,
			FileNotFoundException {
		InputStream is = httpcon.getInputStream();

		Drawable drawable = Drawable.createFromStream(is, "src");

		// 是否保存图标
		if (drawable != null && isSaveIcon) {
			if (FolderOper.isExistSdcard(context)) {
				// 创建文件�?
				try {
					FolderOper
							.createSDCardDir(HctConstants.DEFAULT_CACHE_STORE_PATH);
				} catch (Exception e) {
					e.printStackTrace();
				}
				File iconFile = new File(HctConstants.DEFAULT_ROOT_PATH
						+ HctConstants.DEFAULT_CACHE_STORE_PATH + savePhotoName);
				BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
				Bitmap bitMap = bitmapDrawable.getBitmap();
				BufferedOutputStream stream = new BufferedOutputStream(
						new FileOutputStream(iconFile));
				bitMap.compress(Bitmap.CompressFormat.PNG, 100, stream);
				stream.flush();
				stream.close();

			}
		}
		return drawable;
	}

	private final static int BUFFER_SIZE = 4096;

	private byte[] getByte(InputStream is) throws Exception {
		ByteArrayOutputStream outStream = new ByteArrayOutputStream();
		byte[] data = new byte[BUFFER_SIZE];
		int count = -1;
		while ((count = is.read(data, 0, BUFFER_SIZE)) != -1)
			outStream.write(data, 0, count);

		data = null;
		return outStream.toByteArray();
	}

	public interface ImageCallback {
		public void imageLoaded(Drawable imageDrawable, String imageUrl);
	}

	/**
	 * 清除缓存的位图
	 */
	public void clearCache() {
		if (imageCache == null || imageCache.size() == 0) {
			return;
		}
		if (imageCache.size() > 0) {

			imageCache.evictAll();
		}
		imageCache = null;

	}

}
